use aho_corasick::AhoCorasick;

use crate::base::parse_date;

pub fn get_perd<'a>(paras: Vec<&'a str>) -> anyhow::Result<String> {
    let plen = paras.len();
    if !(plen >= 3 && plen <= 5) {
        return Err(anyhow::anyhow!(
            "get_perd需要3到5个参数，而提供了{plen}个！"
        ));
    }
    let itno = paras[0];
    let mut item5 = "";
    if itno.len() >= 5 {
        item5 = &itno[0..5]
    }
    if plen >= 4 && (item5 == "20201" || item5 == "20202") {
        let term = paras[3];
        if term == "1" {
            return Ok("101".to_owned());
        } else {
            return Ok("107".to_owned());
        }
    }
    let mut item3 = "";
    if itno.len() >= 3 {
        item3 = &itno[0..3]
    }
    if plen == 5 {
        let cd = paras[4];
        if item3 == "201" && cd == "20" {
            return Ok("88".to_owned());
        }
    }
    if item3 == "201"
        || item3 == "243"
        || item3 == "252"
        || item3 == "211"
        || item3 == "221"
        || item3 == "222"
    {
        return Ok("0".to_owned());
    }
    if paras[1].is_empty() || paras[2].is_empty() || paras[1] == "0" || paras[2] == "0" {
        return Ok("0".to_owned());
    }
    let sdate = parse_date(paras[1])
        .or_else(|err| Err(anyhow::anyhow!("get_perd的第2个参数{}:{err}", paras[1])))?;
    let edate = parse_date(paras[2])
        .or_else(|err| Err(anyhow::anyhow!("get_perd的第3个参数{}:{err}", paras[2])))?;
    let dura = edate - sdate;
    let days = dura.num_days() + 1;
    match days {
        0..=1 => return Ok("101".to_owned()),
        2..=7 => return Ok("107".to_owned()),
        8..=14 => return Ok("114".to_owned()),
        15..=31 => return Ok("1".to_owned()),
        32..=62 => return Ok("2".to_owned()),
        63..=93 => return Ok("3".to_owned()),
        94..=124 => return Ok("4".to_owned()),
        125..=155 => return Ok("5".to_owned()),
        156..=186 => return Ok("6".to_owned()),
        187..=217 => return Ok("7".to_owned()),
        218..=248 => return Ok("8".to_owned()),
        249..=279 => return Ok("9".to_owned()),
        280..=310 => return Ok("10".to_owned()),
        311..=341 => return Ok("11".to_owned()),
        342..=400 => return Ok("12".to_owned()),
        401..=800 => return Ok("24".to_owned()),
        801..=1098 => return Ok("36".to_owned()),
        1099..=1464 => return Ok("48".to_owned()),
        1465..=1830 => return Ok("60".to_owned()),
        1831..=2196 => return Ok("72".to_owned()),
        2197..=2562 => return Ok("84".to_owned()),
        2563..=2928 => return Ok("96".to_owned()),
        2929..=3660 => return Ok("120".to_owned()),
        3661..=5490 => return Ok("180".to_owned()),
        _ => return Ok("240".to_owned()),
    }
}

//修改对公客户名称
pub fn modify_comp_clie_name<'a>(paras: Vec<&'a str>) -> anyhow::Result<String> {
    let plen = paras.len();
    if plen != 1 {
        return Err(anyhow::anyhow!(
            "modify_comp_cLie_name需要1个参数，而提供了{}个！",
            plen
        ));
    }
    let cunm = paras[0];
    let svals = &["（1101）", "（1101", "(1101)", "(1101", "(", ")"];
    let rvals = &["", "", "", "", "（", "）"];
    let ac = AhoCorasick::builder().build(svals).unwrap();
    let mut wtr = vec![];
    ac.try_stream_replace_all(cunm.as_bytes(), &mut wtr, rvals)
        .or_else(|err| {
            Err(anyhow::anyhow!(
                "执行modify_comp_cLie_name替换字符串时发生错误：{}",
                err
            ))
        })?;
    let cunm = String::from_utf8(wtr).unwrap();
    Ok(cunm)
}
pub fn substr<'a>(paras: Vec<&'a str>) -> anyhow::Result<String> {
    let plen = paras.len();
    if plen != 3 {
        return Err(anyhow::anyhow!("substr需要3个参数，而提供了{}个！", plen));
    }
    let s = paras[0];
    let start = paras[1]
        .parse::<u32>()
        .or_else(|_| Err(anyhow::anyhow!("第2个参数开始位置{}不是u32类型", paras[1])))?;
    let count = paras[2]
        .parse::<u32>()
        .or_else(|_| Err(anyhow::anyhow!("第3个参数个数{}不是u32类型", paras[1])))?;
    Ok(s.chars()
        .skip(start as usize)
        .take(count as usize)
        .collect::<String>())
}
pub fn get_clie_type_by_no(paras: Vec<&str>) -> anyhow::Result<String> {
    let plen = paras.len();
    if plen != 1 {
        return Err(anyhow::anyhow!(
            "get_clie_type_by_no需要1个参数，而提供了{}个！",
            plen
        ));
    }
    let cuno = paras[0];
    if cuno.is_empty() {
        return Ok("".to_owned());
    }
    let cutp = &cuno[0..1];
    let outval = if cutp == "P" { "1" } else { "0" };
    Ok(outval.to_owned())
}
pub fn if_empty(paras: Vec<&str>) -> anyhow::Result<String> {
    let plen = paras.len();
    if plen != 2 {
        return Err(anyhow::anyhow!("if_empty需要2个参数，而提供了{}个！", plen));
    }
    let str1 = paras[0];
    if str1.is_empty() {
        return Ok(paras[1].to_owned());
    }
    Ok(str1.to_owned())
}

pub fn remove_tail_letters(paras: Vec<&str>) -> anyhow::Result<String> {
    let plen = paras.len();
    if plen != 2 {
        return Err(anyhow::anyhow!(
            "remove_tail_letters需要2个参数，而提供了{}个！",
            plen
        ));
    }
    let input = paras[0];
    let res: String = input
        .chars()
        .rev() // 将字符串逆序
        .take_while(|c| c.is_uppercase() && c.is_ascii_alphabetic()) // 取直到遇到非大写字母字符
        .collect::<String>()
        .chars()
        .rev() // 再将结果逆序回来
        .collect();
    Ok(res)
}
